# coding:utf-8
"""
    这个例子通过python-nmap实现一个高效的端口扫描工具,与定时作业crontab及邮件告警结合.

    采用了三层for循环,第一层遍历要扫描的主机,第二层为遍历协议,第三层为遍历端口,最后输出主机状态.
"""

import sys

import nmap

scan_row = [ ]
input_data = input('Please input hosts and port: ')
scan_row=input_data.split(" ") 

if len(scan_row)!=2:
    print("Input errors,example '192.168.1.0/24 80,443,22' ")
    sys.exit(0)

hosts = scan_row[0]  # 接收用户输入的主机
port = scan_row[1]  # 接收用户输入的端口

# try:
    nm = nmap.PortScanner()  # 创建端口扫描对象
# except nmap.PortScannerError:
#     print('Nmap not found', sys.exc_info()[0])
#     sys.exit(0)
# except:
#     print("Unexpected error:", sys.exc_info()[0])
#     sys.exit(0)

try:
    # 调用扫描方法,参数指定扫描主机hosts, namp扫描命令行参数arguments
    nm.scan(hosts = hosts, arguments=' -V -sS -p '+port)
except expression as identifier:
    print('Scan error: ' + str(identifier))
    
for host in nm.all_hosts(): # 遍历扫描主机
    print('-------------------------------------------------------')
    print('Host : %s (%s)' % (host, nm[hosts].hostname()))
    print('State : %s' % nm[host].state()) # 输出主机状态
    for proto in nm[hosts].all_protocols(): # 遍历扫描协议
        print('-----------')
        print('Protocol : %s' % proto) # 输入协议名

        lport = nm[host][proto].keys() # 获取协议的所有扫描端口
        lport.sort() # 端口列表排序
        for port in lport: # 遍历端口及输出端口与状态
            print('port : %s\tstate : %s' % (port, nm[host][proto][port]['state']))